package com.suning.sawp.service.impl.bi;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.dto.bi.BiSaleAmountDto;
import com.suning.sawp.dto.bi.sale.SaleCategory;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.intf.bi.BiBrandDaoService;
import com.suning.sawp.intf.bi.BiBrandService;
import com.suning.sawp.intf.bi.BiKafkaRealTimeSaleService;
import com.suning.sawp.intf.bi.BiStoreDateService;
import com.suning.sawp.intf.bi.StoreGuideBiService;
import com.suning.sawp.po.bi.BiBrandSale;
import com.suning.sawp.po.bi.BiBrandSaleInfoDto;
import com.suning.sawp.po.bi.BiBrandSaleResult;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.DateUtils;

@Service("biBrandService")
public class BiBrandServiceImpl implements BiBrandService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstants.SAWP_BI);

    @Resource
    BiBrandDaoService biBrandDaoService;

    @Resource
    StoreGuideBiService storeGuideBiService;

    @Resource
    BiStoreDateService biStoreDateService;

    /**
     * BI实时销售数据接口服务
     */
    @Autowired
    BiKafkaRealTimeSaleService biKafkaRealTimeSaleService;

    private static final String ORDER_BY_AMOUNT = "0";

    @Override
    public ReturnMsg<BiBrandSaleInfoDto> queryBrandSaleByDay(String cateCode, String queryTime, String orderCondition,
            StoreManDto storeManDto) {
        ReturnMsg<BiBrandSaleInfoDto> resultMsg = new ReturnMsg<BiBrandSaleInfoDto>();

        if (storeManDto == null) {
            resultMsg.setError(ErrorCodeConstants.ERR_0001);
            LOGGER.error("queryBrandSaleByDay storeManDto  is  null  cateCode is blockateCode:{},queryTime:{}",
                    cateCode, queryTime);
            return resultMsg;
        }

        LOGGER.info("queryBrandSaleByDay ,cateCode:{},queryTime:{},staffId:{}", cateCode, queryTime,
                storeManDto.getStaffId());
        BiBrandSaleInfoDto biBrandSaleInfoDto = new BiBrandSaleInfoDto();
        List<SaleCategory> cateList = storeGuideBiService.getBlongGategories(storeManDto, cateCode);
        biBrandSaleInfoDto.setCateList(cateList);
        if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId()) && StringUtils.isBlank(cateCode)) {
            for (SaleCategory saleCategory : cateList) {
                if (saleCategory != null && SaleCategory.ChooseStatus.YES.equals(saleCategory.getChooseStatus())) {
                    cateCode = saleCategory.getCateCode();
                    break;
                }
            }
        }

        if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId()) && StringUtils.isBlank(cateCode)) {
            resultMsg.setError(ErrorCodeConstants.ERR_0001);
            LOGGER.error("queryBrandSaleByDay cateCode is blockateCode:{},queryTime:{},staffId:{}", cateCode,
                    queryTime, storeManDto.getStaffId());
            return resultMsg;
        }

        List<BiBrandSale> brandList;

        try {
            if (DateUtils.getDateStrByFormat(null, "yyyy-MM-dd").equals(queryTime)) {
                brandList = getBrandSaleByDay(cateCode, orderCondition, storeManDto.getStoreCode());
            } else {
                brandList = biBrandDaoService.queryBrandSaleByDay(cateCode, queryTime, storeManDto.getStoreCode(),
                        orderCondition);
            }

            final String orderConditionTmp = orderCondition;
            List<BiBrandSaleResult> schemeResultList = Lists.newArrayList(Lists.transform(brandList,
                    new Function<BiBrandSale, BiBrandSaleResult>() {
                        @Override
                        public BiBrandSaleResult apply(BiBrandSale input) {
                            BiBrandSaleResult biBrandSaleResult = new BiBrandSaleResult();
                            if (input == null) {
                                return null;
                            }
                            // 销售总计
                            biBrandSaleResult.setTotalAmount(BiSaleAmountDto.valueOf(input.getBrandAmount()));
                            // 品牌编码
                            biBrandSaleResult.setBrandCode(input.getBrandCode());
                            // 品牌名称
                            biBrandSaleResult.setBrandName(input.getBrandName());
                            // 品类编码
                            biBrandSaleResult.setCateCode(input.getCateCode());

                            String brandRate = "0.0";
                            if (ORDER_BY_AMOUNT.equals(orderConditionTmp)) {
                                // 品牌在品类中的销售额占比
                                if (input.getBrandAmount() != null && input.getCateAmount() != null) {
                                    brandRate = DJStringUtils.calculateRateString(input.getBrandAmount().toString(),
                                            input.getCateAmount().toString());
                                }
                            } else {
                                // 品牌在品类中的销量占比
                                if (input.getSaleCnt() != null && input.getCateCnt() != null) {
                                    brandRate = DJStringUtils.calculateRateString(input.getSaleCnt().toString(), input
                                            .getCateCnt().toString());
                                }
                            }
                            biBrandSaleResult.setBrandRate(brandRate);
                            biBrandSaleResult.setPositiveAmt(BiSaleAmountDto.valueOf(input.getPositiveSaleAmount()));
                            // 退款金额
                            biBrandSaleResult.setRefundAmt(BiSaleAmountDto.valueOf(input.getNegativeSaleAmount()));
                            // 销售数量
                            biBrandSaleResult.setSaleCnt(input.getSaleCnt());
                            biBrandSaleResult.setPositiveCnt(input.getPositiveSaleCnt());
                            biBrandSaleResult.setRefundCnt(input.getNegativeSaleCnt());
                            // 同比
                            String saleRate = "0.0";
                            if (ORDER_BY_AMOUNT.equals(orderConditionTmp)) {
                                // 销售额同比
                                if (input.getBrandAmount() != null && input.getBrandAmountLy() != null) {
                                    saleRate = DJStringUtils.calculateYoyString(input.getBrandAmount(),
                                            input.getBrandAmountLy());
                                }
                            } else {
                                // 销量同比
                                if (input.getSaleCnt() != null && input.getCateCnt() != null) {
                                    saleRate = DJStringUtils.calculateYoyString(input.getSaleCnt(),
                                            input.getBrandCntLy());
                                }
                            }
                            biBrandSaleResult.setSaleRate(saleRate);
                            return biBrandSaleResult;
                        }
                    }));

            biBrandSaleInfoDto.setBrandList(schemeResultList);
            LOGGER.info("queryBrandSaleByDay ,mainPushStaffVo:{}", biBrandSaleInfoDto);
            resultMsg.setData(biBrandSaleInfoDto);
        } catch (Exception e) {
            resultMsg.setError(ErrorCodeConstants.ERR_0002);
            LOGGER.error("queryBrandSaleByDay Exception", e);
        }
        return resultMsg;

    }

    @Override
    public ReturnMsg<BiBrandSaleInfoDto> queryBrandSaleByMonth(String cateCode, String queryTime,
            String orderCondition, StoreManDto storeManDto) {
        ReturnMsg<BiBrandSaleInfoDto> resultMsg = new ReturnMsg<BiBrandSaleInfoDto>();

        if (storeManDto == null) {
            resultMsg.setError(ErrorCodeConstants.ERR_0001);
            LOGGER.error("queryBrandSaleByDay storeManDto  is  null  cateCode is blockateCode:{},queryTime:{}",
                    cateCode, queryTime);
            return resultMsg;
        }

        LOGGER.info("queryBrandSaleByMonth ,cateCode:{},queryTime:{},staffId:{}", cateCode, queryTime,
                storeManDto.getStaffId());
        BiBrandSaleInfoDto biBrandSaleInfoDto = new BiBrandSaleInfoDto();
        List<SaleCategory> cateList = storeGuideBiService.getBlongGategories(storeManDto, cateCode);
        biBrandSaleInfoDto.setCateList(cateList);
        if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId()) && StringUtils.isBlank(cateCode)) {
            for (SaleCategory saleCategory : cateList) {
                if (saleCategory != null && SaleCategory.ChooseStatus.YES.equals(saleCategory.getChooseStatus())) {
                    cateCode = saleCategory.getCateCode();
                    break;
                }
            }
        }

        if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId()) && StringUtils.isBlank(cateCode)) {
            resultMsg.setError(ErrorCodeConstants.ERR_0001);
            LOGGER.error("queryBrandSaleByMonth cateCode is blockateCode:{},queryTime:{},staffId:{}", cateCode,
                    queryTime, storeManDto.getStaffId());
            return resultMsg;
        }

        try {

            List<BiBrandSale> brandList = biBrandDaoService.queryBrandSaleByMonth(cateCode, queryTime,
                    storeManDto.getStoreCode(), orderCondition);
            final String orderConditionTmp = orderCondition;
            List<BiBrandSaleResult> schemeResultList = Lists.newArrayList(Lists.transform(brandList,
                    new Function<BiBrandSale, BiBrandSaleResult>() {
                        @Override
                        public BiBrandSaleResult apply(BiBrandSale input) {
                            BiBrandSaleResult biBrandSaleResult = new BiBrandSaleResult();
                            if (input == null) {
                                return null;
                            }
                            // 销售总计
                            biBrandSaleResult.setTotalAmount(BiSaleAmountDto.valueOf(input.getBrandAmount()));
                            // 品牌编码
                            biBrandSaleResult.setBrandCode(input.getBrandCode());
                            // 品牌名称
                            biBrandSaleResult.setBrandName(input.getBrandName());
                            // 品类编码
                            biBrandSaleResult.setCateCode(input.getCateCode());

                            String brandRate = "0.0";
                            if (ORDER_BY_AMOUNT.equals(orderConditionTmp)) {
                                // 品牌在品类中的销售额占比
                                if (input.getBrandAmount() != null && input.getCateAmount() != null) {
                                    brandRate = DJStringUtils.calculateRateString(input.getBrandAmount().toString(),
                                            input.getCateAmount().toString());
                                }
                            } else {
                                // 品牌在品类中的销量占比
                                if (input.getSaleCnt() != null && input.getCateCnt() != null) {
                                    brandRate = DJStringUtils.calculateRateString(input.getSaleCnt().toString(), input
                                            .getCateCnt().toString());
                                }
                            }
                            biBrandSaleResult.setBrandRate(brandRate);
                            biBrandSaleResult.setPositiveAmt(BiSaleAmountDto.valueOf(input.getPositiveSaleAmount()));
                            // 退款金额
                            biBrandSaleResult.setRefundAmt(BiSaleAmountDto.valueOf(input.getNegativeSaleAmount()));
                            // 销售数量
                            biBrandSaleResult.setSaleCnt(input.getSaleCnt());
                            biBrandSaleResult.setPositiveCnt(input.getPositiveSaleCnt());
                            biBrandSaleResult.setRefundCnt(input.getNegativeSaleCnt());
                            
                            
                            String saleRate = "0.0";
                            // 同比
                            if (ORDER_BY_AMOUNT.equals(orderConditionTmp)) {
                                // 销售额同比
                                if (input.getBrandAmount() != null && input.getBrandAmountLy() != null) {
                                    saleRate = DJStringUtils.calculateYoyString(input.getBrandAmount(),
                                            input.getBrandAmountLy());
                                }
                            } else {
                                // 销量同比
                                if (input.getSaleCnt() != null && input.getCateCnt() != null) {
                                    saleRate = DJStringUtils.calculateYoyString(input.getSaleCnt(),
                                            input.getBrandCntLy());
                                }
                            }
                            
                            biBrandSaleResult.setSaleRate(saleRate);
                            return biBrandSaleResult;
                        }
                    }));

            biBrandSaleInfoDto.setBrandList(schemeResultList);
            LOGGER.info("queryBrandSaleByMonth ,mainPushStaffVo:{}", biBrandSaleInfoDto);
            resultMsg.setData(biBrandSaleInfoDto);
        } catch (Exception e) {
            resultMsg.setError(ErrorCodeConstants.ERR_0002);
            LOGGER.error("queryBrandSaleByMonth Exception", e);
        }
        return resultMsg;

    }

    public List<BiBrandSale> getBrandSaleByDay(String cateCodeQr, String orderCondition, String storeCode) {

        LOGGER.info("getBrandSaleByDay,cateCodeQr:{},orderCondition:{},storeCode:{}", cateCodeQr, orderCondition,
                storeCode);

        // 查询门店该品类下品牌实时销售数据，如果品牌为空查询全部
        List<Map<String, Object>> cateSales = biKafkaRealTimeSaleService.getStoreBrandSaleDataByCateFromRedis(
                storeCode, cateCodeQr);

        // 数据不为空时
        if (CollectionUtils.isEmpty(cateSales)) {
            return Collections.emptyList();
        }

        final String orderConditionTmp = ORDER_BY_AMOUNT.equals(orderCondition) ? "payAmt" : "saleCnt";

        // 根据销售额排序
        Collections.sort(cateSales, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                if (null != o2.get(orderConditionTmp) && null != o1.get(orderConditionTmp)) {
                    return DJStringUtils.bigDecimal(String.valueOf(o2.get(orderConditionTmp))).compareTo(
                            DJStringUtils.bigDecimal(String.valueOf(o1.get(orderConditionTmp))));
                } else if (null == o2.get(orderConditionTmp)) {
                    return -1;
                } else if (null == o1.get(orderConditionTmp)) {
                    return 1;
                }
                // 降序
                return 0;
            }
        });

        List<BiBrandSale> cateSaleList = new ArrayList<BiBrandSale>();
        for (Map<String, Object> sale : cateSales) {
            if (cateSaleList.size() >= 20) {
                break;
            }

            if (null == sale) {
                continue;
            }
            // 获取品类编码
            String cateCode = String.valueOf(sale.get("deptCd"));
            String cateName = ConfigConstants.DEFAULT_CATE_MAP.get(cateCode);
            // 判断品类编码和品类名称是否为空
            if (StringUtils.isBlank(cateCode) || StringUtils.isBlank(cateName)) {
                // 如果品类编码,或者品类名称不存在,则不处理该品类信息
                continue;
            }
            BiBrandSale cateDetail = new BiBrandSale();

            // 品牌销售额
            BigDecimal brandSaleAmount;
            if (null != sale.get("payAmt")) {
                brandSaleAmount = new BigDecimal(String.valueOf(sale.get("payAmt")));
            } else {
                brandSaleAmount = new BigDecimal("0.00");
            }
            cateDetail.setBrandAmount(brandSaleAmount);
            // 品牌销售数量
            BigDecimal brandSaleCnt;
            if (null != sale.get("saleCnt")) {
                brandSaleCnt = new BigDecimal(String.valueOf(sale.get("saleCnt")));
            } else {
                brandSaleCnt = new BigDecimal("0.00");
            }
            cateDetail.setSaleCnt(brandSaleCnt);

            // 同期销售额，实时数据不计算统计默认0
            cateDetail.setBrandAmountLy(new BigDecimal("0.00"));
            cateDetail.setBrandCode(String.valueOf(sale.get("brandCd")));
            cateDetail.setBrandName(String.valueOf(sale.get("brandName")));

            Map<String, Object> temMap = biKafkaRealTimeSaleService.getStoreCateSaleDataFromRedis(storeCode, cateCode);
            if (temMap != null && !temMap.isEmpty()) {
                // 品类销售额
                if (null != temMap.get("payAmt")) {
                    cateDetail.setCateAmount(new BigDecimal(String.valueOf(temMap.get("payAmt"))));
                } else {
                    cateDetail.setCateAmount(new BigDecimal("0.00"));
                }

                // 品牌销量
                if (null != temMap.get("saleCnt")) {
                    cateDetail.setCateCnt(new BigDecimal(String.valueOf(temMap.get("saleCnt"))));
                } else {
                    cateDetail.setCateCnt(new BigDecimal("0.00"));
                }
            }

            // 品类编码
            cateDetail.setCateCode(cateCode);

            // 正向数据
            BigDecimal positiveSaleAmount;
            BigDecimal positiveSaleCnt;
            // 正向销售额
            if (null != sale.get("payAmt_f")) {
                positiveSaleAmount = new BigDecimal(String.valueOf(sale.get("payAmt_f")));
            } else {
                positiveSaleAmount = new BigDecimal("0.00");
            }
            cateDetail.setPositiveSaleAmount(positiveSaleAmount);
            // 正向销量
            if (null != sale.get("saleCnt_f")) {
                positiveSaleCnt = new BigDecimal(String.valueOf(sale.get("saleCnt_f")));
            } else {
                positiveSaleCnt = new BigDecimal("0.00");
            }
            cateDetail.setPositiveSaleCnt(positiveSaleCnt);

            // 逆向数据
            BigDecimal negativeSaleAmount;
            BigDecimal negativeSaleCnt;
            // 逆向销售额
            if (null != sale.get("payAmt_r")) {
                negativeSaleAmount = new BigDecimal(String.valueOf(sale.get("payAmt_r")));
            } else {
                negativeSaleAmount = new BigDecimal("0.00");
            }
            cateDetail.setNegativeSaleAmount(negativeSaleAmount);
            // 逆向销量
            if (null != sale.get("saleCnt_r")) {
                negativeSaleCnt = new BigDecimal(String.valueOf(sale.get("saleCnt_r")));
            } else {
                negativeSaleCnt = new BigDecimal("0.00");
            }
            cateDetail.setNegativeSaleCnt(negativeSaleCnt);

            cateSaleList.add(cateDetail);
        }
        return cateSaleList;

    }
}
